package com.linovi.functions

class Functions {

  def partial[Arg1, Arg2, Result](a: Arg1, f: (Arg1, Arg2) => Result): Arg2 => Result = (b: Arg2) => f(a, b)

  def curry[Arg1, Arg2, Result](f: (Arg1, Arg2) => Result): Arg1 => (Arg2 => Result) = (a: Arg1) => (b: Arg2) => f(a, b)

  def uncurry[Arg1, Arg2, Result](f: Arg1 => Arg2 => Result): (Arg1, Arg2) => Result = (a: Arg1, b: Arg2) => f(a)(b)

  def compose[Arg1, Arg2, Result](f: Arg2 => Result, g: Arg1 => Arg2): Arg1 => Result = (a: Arg1) => f(g(a))

}

object Functions {
  def main(args: Array[String]) {
	  
    var a : Functions = new Functions
    def func1(a: Int, b: Int) = a + b
    
    var res = a.partial(5, func1)
    println(res(3))
    
    var res2 = a.curry(func1)
    println(res2(3)(9))

    var res3 = a.uncurry(res2)
    println(res3(3, 6))
    
    var res4 = a.compose(res2, res)
    println(res4(7)(10))
    
  }
}